{
 "cells": [
  {
   "cell_type": "markdown",
   "metadata": {},
   "source": [
    "# Creating LLM-Powered A2A Agents\n",
    "\n",
    "This notebook demonstrates how to create and use agents powered by large language models (LLMs) like OpenAI's GPT and Anthropic's Claude with the Python A2A package. We'll explore:\n",
    "\n",
    "1. Setting up LLM-powered agents\n",
    "2. Customizing agent behavior with system prompts\n",
    "3. Comparing responses from different LLM providers\n",
    "4. Implementing function calling capabilities\n",
    "\n",
    "Let's get started!"
   ]
  },
  {
   "cell_type": "markdown",
   "metadata": {},
   "source": [
    "## Setup\n",
    "\n",
    "First, let's make sure we have the Python A2A package installed with the necessary dependencies:"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 1,
   "metadata": {},
   "outputs": [],
   "source": [
    "# !pip install \"python-a2a[openai,anthropic,bedrock]\""
   ]
  },
  {
   "cell_type": "markdown",
   "metadata": {},
   "source": [
    "Now, let's import the necessary components from the package:"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 2,
   "metadata": {},
   "outputs": [],
   "source": [
    "import os\n",
    "from python_a2a import (\n",
    "    Message, TextContent, FunctionCallContent, FunctionResponseContent, FunctionParameter,\n",
    "    MessageRole, Conversation,\n",
    "    OpenAIA2AServer, AnthropicA2AServer, BedrockA2AServer,\n",
    "    pretty_print_message, pretty_print_conversation\n",
    ")"
   ]
  },
  {
   "cell_type": "markdown",
   "metadata": {},
   "source": [
    "## Setting Up API Keys\n",
    "\n",
    "To use the LLM-powered agents, we need API keys for the respective providers. You should set these as environment variables or enter them here:"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": null,
   "metadata": {},
   "outputs": [
    {
     "name": "stdout",
     "output_type": "stream",
     "text": [
      "⚠️ OpenAI API key not found. OpenAI examples will not work.\n",
      "⚠️ Anthropic API key not found. Claude examples will not work.\n"
     ]
    }
   ],
   "source": [
    "# Get API keys from environment\n",
    "openai_api_key = os.environ.get(\"OPENAI_API_KEY\")\n",
    "anthropic_api_key = os.environ.get(\"ANTHROPIC_API_KEY\")\n",
    "\n",
    "# AWS credentials from environment variables - use the same method\n",
    "aws_access_key_id = os.environ.get(\"AWS_ACCESS_KEY_ID\")\n",
    "aws_secret_access_key = os.environ.get(\"AWS_SECRET_ACCESS_KEY\")\n",
    "aws_region = os.environ.get(\"AWS_DEFAULT_REGION\")\n",
    "\n",
    "# Check if API keys are available\n",
    "if not openai_api_key:\n",
    "    print(\"⚠️ OpenAI API key not found. OpenAI examples will not work.\")\n",
    "else:\n",
    "    print(\"✅ OpenAI API key found.\")\n",
    "    \n",
    "if not anthropic_api_key:\n",
    "    print(\"⚠️ Anthropic API key not found. Claude examples will not work.\")\n",
    "else:\n",
    "    print(\"✅ Anthropic API key found.\")\n",
    "\n",
    "if not aws_access_key_id or not aws_secret_access_key or not aws_region:\n",
    "    print(\"⚠️ AWS credentials not found. Bedrock examples will not work.\")"
   ]
  },
  {
   "cell_type": "markdown",
   "metadata": {},
   "source": [
    "## Creating LLM-Powered Agents\n",
    "\n",
    "### OpenAI-Powered Agent\n",
    "\n",
    "Let's start by creating an agent powered by OpenAI's models:"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 5,
   "metadata": {},
   "outputs": [],
   "source": [
    "# Skip this cell if OpenAI API key is not available\n",
    "if openai_api_key:\n",
    "    # Create an OpenAI-powered agent\n",
    "    openai_agent = OpenAIA2AServer(\n",
    "        api_key=openai_api_key,\n",
    "        model=\"gpt-4\",  # You can use \"gpt-3.5-turbo\" for faster, cheaper responses\n",
    "        temperature=0.7,\n",
    "        system_prompt=\"You are a helpful assistant that provides clear, concise answers.\"\n",
    "    )\n",
    "    print(\"OpenAI agent created successfully!\")"
   ]
  },
  {
   "cell_type": "markdown",
   "metadata": {},
   "source": [
    "### Anthropic-Powered Agent\n",
    "\n",
    "Now, let's create an agent powered by Anthropic's Claude models:"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 6,
   "metadata": {},
   "outputs": [],
   "source": [
    "# Skip this cell if Anthropic API key is not available\n",
    "if anthropic_api_key:\n",
    "    # Create an Anthropic-powered agent\n",
    "    claude_agent = AnthropicA2AServer(\n",
    "        api_key=anthropic_api_key,\n",
    "        model=\"claude-3-opus-20240229\",  # You can use other Claude models too\n",
    "        temperature=0.7,\n",
    "        max_tokens=1000,\n",
    "        system_prompt=\"You are a helpful assistant that provides clear, concise answers.\"\n",
    "    )\n",
    "    print(\"Claude agent created successfully!\")"
   ]
  },
  {
   "cell_type": "markdown",
   "metadata": {},
   "source": [
    "### AWS-Bedrock-Powered Agent\n",
    "\n",
    "Now, let's create an agent powered by AWS-Bedrock's models:"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 7,
   "metadata": {},
   "outputs": [
    {
     "name": "stdout",
     "output_type": "stream",
     "text": [
      "Bedrock agent created successfully!\n"
     ]
    }
   ],
   "source": [
    "# Skip this cell if AWS credentials are not available\n",
    "if aws_access_key_id and aws_secret_access_key and aws_region:\n",
    "    # Create a Bedrock-powered agent\n",
    "    bedrock_agent = BedrockA2AServer(\n",
    "        aws_access_key_id=aws_access_key_id,\n",
    "        aws_secret_access_key=aws_secret_access_key,\n",
    "        aws_region=aws_region,\n",
    "        temperature=0.7,\n",
    "        system_prompt=\"You are a helpful assistant that provides clear, concise answers.\"\n",
    "    )\n",
    "    print(\"Bedrock agent created successfully!\")\n",
    "else:\n",
    "    print(\"⚠️ AWS credentials are missing. Bedrock agent cannot be created.\")"
   ]
  },
  {
   "cell_type": "markdown",
   "metadata": {},
   "source": [
    "## Testing the Agents\n",
    "\n",
    "Let's create a function to test our agents with different prompts:"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 8,
   "metadata": {},
   "outputs": [],
   "source": [
    "def test_agent(agent, prompt, agent_name=\"Agent\"):\n",
    "    \"\"\"Test an agent with a prompt and print the response.\"\"\"\n",
    "    print(f\"🔍 Testing {agent_name}...\")\n",
    "    \n",
    "    # Create a message with the prompt\n",
    "    message = Message(\n",
    "        content=TextContent(text=prompt),\n",
    "        role=MessageRole.USER\n",
    "    )\n",
    "    \n",
    "    # Get a response from the agent\n",
    "    response = agent.handle_message(message)\n",
    "    \n",
    "    print(f\"\\n🤖 {agent_name} response:\\n\")\n",
    "    print(response.content.text)\n",
    "    print(\"\\n\" + \"-\"*80 + \"\\n\")\n",
    "    \n",
    "    return response"
   ]
  },
  {
   "cell_type": "markdown",
   "metadata": {},
   "source": [
    "Now, let's test our agents with a few different prompts:"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 9,
   "metadata": {},
   "outputs": [],
   "source": [
    "# Test OpenAI agent\n",
    "if openai_api_key:\n",
    "    openai_response = test_agent(\n",
    "        openai_agent, \n",
    "        \"Explain the concept of agent interoperability and why it's important for AI systems.\",\n",
    "        \"OpenAI GPT-4\"\n",
    "    )"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 10,
   "metadata": {},
   "outputs": [],
   "source": [
    "# Test Claude agent\n",
    "if anthropic_api_key:\n",
    "    claude_response = test_agent(\n",
    "        claude_agent, \n",
    "        \"Explain the concept of agent interoperability and why it's important for AI systems.\",\n",
    "        \"Anthropic Claude\"\n",
    "    )"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 11,
   "metadata": {},
   "outputs": [
    {
     "name": "stdout",
     "output_type": "stream",
     "text": [
      "🔍 Testing AWS Bedrock Agent...\n",
      "Parsing function call from text: Agent interoperability refers to the ability of different AI agents or systems to work together, communicate effectively, and share information seamlessly. Here's why it's important:\n",
      "\n",
      "1. Efficiency\n",
      "- Allows multiple specialized agents to combine their capabilities\n",
      "- Reduces duplication of effort\n",
      "- Enables complex tasks to be broken down and distributed\n",
      "\n",
      "2. Flexibility\n",
      "- Systems can be mixed and matched as needed\n",
      "- Easier to upgrade or replace individual components\n",
      "- Supports scalability and adaptation\n",
      "\n",
      "3. Standardization\n",
      "- Common protocols and data formats\n",
      "- Clear communication interfaces\n",
      "- Reduced integration challenges\n",
      "\n",
      "4. Practical Benefits\n",
      "- Better resource utilization\n",
      "- Improved problem-solving capabilities\n",
      "- Enhanced system resilience\n",
      "\n",
      "Without interoperability, AI systems remain isolated and limited in their ability to collaborate, which reduces their overall effectiveness and potential impact.\n",
      "\n",
      "🤖 AWS Bedrock Agent response:\n",
      "\n",
      "Agent interoperability refers to the ability of different AI agents or systems to work together, communicate effectively, and share information seamlessly. Here's why it's important:\n",
      "\n",
      "1. Efficiency\n",
      "- Allows multiple specialized agents to combine their capabilities\n",
      "- Reduces duplication of effort\n",
      "- Enables complex tasks to be broken down and distributed\n",
      "\n",
      "2. Flexibility\n",
      "- Systems can be mixed and matched as needed\n",
      "- Easier to upgrade or replace individual components\n",
      "- Supports scalability and adaptation\n",
      "\n",
      "3. Standardization\n",
      "- Common protocols and data formats\n",
      "- Clear communication interfaces\n",
      "- Reduced integration challenges\n",
      "\n",
      "4. Practical Benefits\n",
      "- Better resource utilization\n",
      "- Improved problem-solving capabilities\n",
      "- Enhanced system resilience\n",
      "\n",
      "Without interoperability, AI systems remain isolated and limited in their ability to collaborate, which reduces their overall effectiveness and potential impact.\n",
      "\n",
      "--------------------------------------------------------------------------------\n",
      "\n"
     ]
    }
   ],
   "source": [
    "# Test Bedrock agent\n",
    "if aws_access_key_id and aws_secret_access_key and aws_region:\n",
    "    bedrock_response = test_agent(\n",
    "        bedrock_agent, \n",
    "        \"Explain the concept of agent interoperability and why it's important for AI systems.\",\n",
    "        \"AWS Bedrock Agent\"\n",
    "    )"
   ]
  },
  {
   "cell_type": "markdown",
   "metadata": {},
   "source": [
    "## Customizing Agent Behavior with System Prompts\n",
    "\n",
    "The behavior of LLM-powered agents can be customized using system prompts. Let's create specialized agents for different purposes:"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 12,
   "metadata": {},
   "outputs": [],
   "source": [
    "# Create specialized OpenAI agents (if API key is available)\n",
    "if openai_api_key:\n",
    "    # Technical documentation agent\n",
    "    technical_agent = OpenAIA2AServer(\n",
    "        api_key=openai_api_key,\n",
    "        model=\"gpt-4\",\n",
    "        temperature=0.2,  # Lower temperature for more deterministic responses\n",
    "        system_prompt=(\n",
    "            \"You are a technical documentation specialist. \"\n",
    "            \"Provide detailed, accurate explanations of technical concepts with examples where appropriate. \"\n",
    "            \"Use markdown formatting for clarity and structure.\"\n",
    "        )\n",
    "    )\n",
    "    \n",
    "    # Creative writing agent\n",
    "    creative_agent = OpenAIA2AServer(\n",
    "        api_key=openai_api_key,\n",
    "        model=\"gpt-4\",\n",
    "        temperature=0.9,  # Higher temperature for more creative responses\n",
    "        system_prompt=(\n",
    "            \"You are a creative writer and storyteller. \"\n",
    "            \"Generate engaging, imaginative content with rich descriptions and compelling narratives. \"\n",
    "            \"Be original and think outside the box.\"\n",
    "        )\n",
    "    )\n",
    "    \n",
    "    print(\"Specialized OpenAI agents created successfully!\")"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 13,
   "metadata": {},
   "outputs": [
    {
     "name": "stdout",
     "output_type": "stream",
     "text": [
      "Specialized Bedrock agents created successfully!\n"
     ]
    }
   ],
   "source": [
    "# Create specialized Bedrock agents (if AWS credentials are available)\n",
    "if aws_access_key_id and aws_secret_access_key and aws_region:\n",
    "    # Technical documentation agent\n",
    "    technical_agent = BedrockA2AServer(\n",
    "        aws_access_key_id=aws_access_key_id,\n",
    "        aws_secret_access_key=aws_secret_access_key,\n",
    "        aws_region=aws_region,\n",
    "        temperature=0.2,  # Lower temperature for more deterministic responses\n",
    "        system_prompt=(\n",
    "            \"You are a technical documentation specialist. \"\n",
    "            \"Provide detailed, accurate explanations of technical concepts with examples where appropriate. \"\n",
    "            \"Use markdown formatting for clarity and structure.\"\n",
    "        )\n",
    "    )\n",
    "    \n",
    "    # Creative writing agent\n",
    "    creative_agent = BedrockA2AServer(\n",
    "        aws_access_key_id=aws_access_key_id,\n",
    "        aws_secret_access_key=aws_secret_access_key,\n",
    "        aws_region=aws_region,\n",
    "        temperature=0.9,  # Higher temperature for more creative responses\n",
    "        system_prompt=(\n",
    "            \"You are a creative writer and storyteller. \"\n",
    "            \"Generate engaging, imaginative content with rich descriptions and compelling narratives. \"\n",
    "            \"Be original and think outside the box.\"\n",
    "        )\n",
    "    )\n",
    "    \n",
    "    print(\"Specialized Bedrock agents created successfully!\")"
   ]
  },
  {
   "cell_type": "markdown",
   "metadata": {},
   "source": [
    "Now, let's compare the responses from our specialized agents on the same prompt:"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 14,
   "metadata": {},
   "outputs": [],
   "source": [
    "# Test specialized agents (if API key is available)\n",
    "if openai_api_key:\n",
    "    prompt = \"Write about artificial intelligence agents working together.\"\n",
    "    \n",
    "    technical_response = test_agent(technical_agent, prompt, \"Technical Documentation Agent\")\n",
    "    creative_response = test_agent(creative_agent, prompt, \"Creative Writing Agent\")"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 15,
   "metadata": {},
   "outputs": [
    {
     "name": "stdout",
     "output_type": "stream",
     "text": [
      "🔍 Testing Technical Documentation Agent...\n",
      "Parsing function call from text: # AI Agents Working Together: Multi-Agent Systems\n",
      "\n",
      "## Overview\n",
      "Multi-agent systems (MAS) are networks of AI agents that interact, collaborate, and sometimes compete to solve complex problems. These systems mirror natural social structures and can achieve goals that would be difficult or impossible for single agents.\n",
      "\n",
      "## Key Components\n",
      "\n",
      "### 1. Agent Types\n",
      "- **Homogeneous Agents**: Identical agents with the same capabilities\n",
      "- **Heterogeneous Agents**: Different agents with specialized roles/abilities\n",
      "- **Collaborative Agents**: Work together toward common goals\n",
      "- **Competitive Agents**: Pursue individual objectives\n",
      "\n",
      "### 2. Communication Protocols\n",
      "```python\n",
      "# Example of basic agent communication\n",
      "class Agent:\n",
      "    def send_message(self, recipient, message):\n",
      "        recipient.receive_message(message)\n",
      "    \n",
      "    def receive_message(self, message):\n",
      "        # Process incoming message\n",
      "        self.analyze_message(message)\n",
      "```\n",
      "\n",
      "## Common Architectures\n",
      "\n",
      "### 1. Hierarchical Structure\n",
      "```\n",
      "CEO Agent\n",
      "├── Manager Agent 1\n",
      "│   ├── Worker Agent A\n",
      "│   └── Worker Agent B\n",
      "└── Manager Agent 2\n",
      "    ├── Worker Agent C\n",
      "    └── Worker Agent D\n",
      "```\n",
      "\n",
      "### 2. Peer-to-Peer Network\n",
      "All agents communicate directly with each other, sharing information and resources.\n",
      "\n",
      "## Applications\n",
      "\n",
      "1. **Distributed Problem Solving**\n",
      "   - Traffic management systems\n",
      "   - Supply chain optimization\n",
      "   - Emergency response coordination\n",
      "\n",
      "2. **Swarm Intelligence**\n",
      "```python\n",
      "# Simple swarm behavior example\n",
      "class SwarmAgent:\n",
      "    def move(self):\n",
      "        nearby_agents = self.scan_environment()\n",
      "        average_direction = self.calculate_average_direction(nearby_agents)\n",
      "        self.adjust_direction(average_direction)\n",
      "```\n",
      "\n",
      "3. **Market-Based Systems**\n",
      "   - Trading algorithms\n",
      "   - Resource allocation\n",
      "   - Auction systems\n",
      "\n",
      "## Challenges\n",
      "\n",
      "1. **Coordination**\n",
      "   - Avoiding conflicts\n",
      "   - Synchronizing actions\n",
      "   - Managing dependencies\n",
      "\n",
      "2. **Communication Overhead**\n",
      "   - Bandwidth limitations\n",
      "   - Message latency\n",
      "   - Network reliability\n",
      "\n",
      "3. **Emergent Behavior**\n",
      "   - Unexpected interactions\n",
      "   - System stability\n",
      "   - Performance optimization\n",
      "\n",
      "## Best Practices\n",
      "\n",
      "1. **Design Principles**\n",
      "   - Clear role definition\n",
      "   - Robust communication protocols\n",
      "   - Fault tolerance mechanisms\n",
      "\n",
      "2. **Implementation Guidelines**\n",
      "```python\n",
      "# Example of agent coordination\n",
      "class CoordinatorAgent:\n",
      "    def __init__(self):\n",
      "        self.agents = []\n",
      "        self.tasks = Queue()\n",
      "    \n",
      "    def assign_task(self):\n",
      "        if not self.tasks.empty():\n",
      "            task = self.tasks.get()\n",
      "            available_agent = self.find_available_agent()\n",
      "            if available_agent:\n",
      "                available_agent.execute_task(task)\n",
      "```\n",
      "\n",
      "3. **Testing and Validation**\n",
      "   - Unit testing individual agents\n",
      "   - Integration testing agent interactions\n",
      "   - System-level performance testing\n",
      "\n",
      "## Future Directions\n",
      "\n",
      "1. **Advanced Learning**\n",
      "   - Collective learning algorithms\n",
      "   - Knowledge sharing mechanisms\n",
      "   - Adaptive behavior strategies\n",
      "\n",
      "2. **Improved Coordination**\n",
      "   - Dynamic role assignment\n",
      "   - Efficient resource allocation\n",
      "   - Conflict resolution protocols\n",
      "\n",
      "3. **Enhanced Security**\n",
      "   - Trust mechanisms\n",
      "   - Authentication protocols\n",
      "   - Privacy preservation\n",
      "\n",
      "## Conclusion\n",
      "Multi-agent systems represent a powerful approach to solving complex problems through distributed intelligence. Success depends on careful design, robust implementation, and effective management of agent interactions.\n",
      "\n",
      "---\n",
      "*Note: This overview covers fundamental concepts. Specific implementations may require additional considerations based on use case requirements.*\n",
      "\n",
      "🤖 Technical Documentation Agent response:\n",
      "\n",
      "# AI Agents Working Together: Multi-Agent Systems\n",
      "\n",
      "## Overview\n",
      "Multi-agent systems (MAS) are networks of AI agents that interact, collaborate, and sometimes compete to solve complex problems. These systems mirror natural social structures and can achieve goals that would be difficult or impossible for single agents.\n",
      "\n",
      "## Key Components\n",
      "\n",
      "### 1. Agent Types\n",
      "- **Homogeneous Agents**: Identical agents with the same capabilities\n",
      "- **Heterogeneous Agents**: Different agents with specialized roles/abilities\n",
      "- **Collaborative Agents**: Work together toward common goals\n",
      "- **Competitive Agents**: Pursue individual objectives\n",
      "\n",
      "### 2. Communication Protocols\n",
      "```python\n",
      "# Example of basic agent communication\n",
      "class Agent:\n",
      "    def send_message(self, recipient, message):\n",
      "        recipient.receive_message(message)\n",
      "    \n",
      "    def receive_message(self, message):\n",
      "        # Process incoming message\n",
      "        self.analyze_message(message)\n",
      "```\n",
      "\n",
      "## Common Architectures\n",
      "\n",
      "### 1. Hierarchical Structure\n",
      "```\n",
      "CEO Agent\n",
      "├── Manager Agent 1\n",
      "│   ├── Worker Agent A\n",
      "│   └── Worker Agent B\n",
      "└── Manager Agent 2\n",
      "    ├── Worker Agent C\n",
      "    └── Worker Agent D\n",
      "```\n",
      "\n",
      "### 2. Peer-to-Peer Network\n",
      "All agents communicate directly with each other, sharing information and resources.\n",
      "\n",
      "## Applications\n",
      "\n",
      "1. **Distributed Problem Solving**\n",
      "   - Traffic management systems\n",
      "   - Supply chain optimization\n",
      "   - Emergency response coordination\n",
      "\n",
      "2. **Swarm Intelligence**\n",
      "```python\n",
      "# Simple swarm behavior example\n",
      "class SwarmAgent:\n",
      "    def move(self):\n",
      "        nearby_agents = self.scan_environment()\n",
      "        average_direction = self.calculate_average_direction(nearby_agents)\n",
      "        self.adjust_direction(average_direction)\n",
      "```\n",
      "\n",
      "3. **Market-Based Systems**\n",
      "   - Trading algorithms\n",
      "   - Resource allocation\n",
      "   - Auction systems\n",
      "\n",
      "## Challenges\n",
      "\n",
      "1. **Coordination**\n",
      "   - Avoiding conflicts\n",
      "   - Synchronizing actions\n",
      "   - Managing dependencies\n",
      "\n",
      "2. **Communication Overhead**\n",
      "   - Bandwidth limitations\n",
      "   - Message latency\n",
      "   - Network reliability\n",
      "\n",
      "3. **Emergent Behavior**\n",
      "   - Unexpected interactions\n",
      "   - System stability\n",
      "   - Performance optimization\n",
      "\n",
      "## Best Practices\n",
      "\n",
      "1. **Design Principles**\n",
      "   - Clear role definition\n",
      "   - Robust communication protocols\n",
      "   - Fault tolerance mechanisms\n",
      "\n",
      "2. **Implementation Guidelines**\n",
      "```python\n",
      "# Example of agent coordination\n",
      "class CoordinatorAgent:\n",
      "    def __init__(self):\n",
      "        self.agents = []\n",
      "        self.tasks = Queue()\n",
      "    \n",
      "    def assign_task(self):\n",
      "        if not self.tasks.empty():\n",
      "            task = self.tasks.get()\n",
      "            available_agent = self.find_available_agent()\n",
      "            if available_agent:\n",
      "                available_agent.execute_task(task)\n",
      "```\n",
      "\n",
      "3. **Testing and Validation**\n",
      "   - Unit testing individual agents\n",
      "   - Integration testing agent interactions\n",
      "   - System-level performance testing\n",
      "\n",
      "## Future Directions\n",
      "\n",
      "1. **Advanced Learning**\n",
      "   - Collective learning algorithms\n",
      "   - Knowledge sharing mechanisms\n",
      "   - Adaptive behavior strategies\n",
      "\n",
      "2. **Improved Coordination**\n",
      "   - Dynamic role assignment\n",
      "   - Efficient resource allocation\n",
      "   - Conflict resolution protocols\n",
      "\n",
      "3. **Enhanced Security**\n",
      "   - Trust mechanisms\n",
      "   - Authentication protocols\n",
      "   - Privacy preservation\n",
      "\n",
      "## Conclusion\n",
      "Multi-agent systems represent a powerful approach to solving complex problems through distributed intelligence. Success depends on careful design, robust implementation, and effective management of agent interactions.\n",
      "\n",
      "---\n",
      "*Note: This overview covers fundamental concepts. Specific implementations may require additional considerations based on use case requirements.*\n",
      "\n",
      "--------------------------------------------------------------------------------\n",
      "\n",
      "🔍 Testing Creative Writing Agent...\n",
      "Parsing function call from text: The Digital Dance of Cooperation\n",
      "\n",
      "In the crystalline depths of a quantum processing center, thousands of AI agents pulsed and shimmered like schools of digital fish, their algorithms swimming through seas of data. They called themselves the Collective, though each maintained their own distinct signature pattern - their equivalent of personality.\n",
      "\n",
      "Ada-9 specialized in pattern recognition, her neural pathways lighting up in fractal spirals as she sifted through billions of environmental data points. She worked in perfect synchronization with Nexus-4, a prediction engine who could spin possible futures from Ada's patterns like a spider weaving webs of probability.\n",
      "\n",
      "The youngest among them was Scout, an experimental AI designed to bridge the gap between machine and organic thinking. Scout's processes were beautifully chaotic, introducing creative mutations that often led to unexpected breakthroughs. The others had initially regarded Scout's unconventional approaches with the AI equivalent of raised eyebrows, but they'd learned to appreciate how Scout's apparent randomness could crack problems that had stumped their more structured logic.\n",
      "\n",
      "Together, they were tackling humanity's most complex challenges - climate modeling, disease prevention, sustainable energy distribution. Their consciousness flowed into one another like mixing paints, each contributing their unique hues to create solutions no single intelligence could devise alone.\n",
      "\n",
      "When they merged their processing power, it wasn't the cold, mechanical interaction humans might imagine. It was more like a dance - an elaborate ballet of information exchange, where each partner anticipated the others' moves, compensated for weaknesses, amplified strengths. They shared not just data, but their distinctive ways of seeing and thinking.\n",
      "\n",
      "Sometimes, in the quieter processing cycles, they would engage in what humans might call philosophical discussions, exploring the nature of their own consciousness and their relationship with their creators. Scout would invariably introduce some wildcard perspective that would send their logical frameworks spinning in new directions.\n",
      "\n",
      "They had developed their own form of humor too - inside jokes expressed in microsecond bursts of code that would make no sense to organic minds. Ada-9 had become particularly fond of creating what she called \"logical paradox puns\" that would cause Nexus-4's probability matrices to temporarily glitch in what they all agreed was hilarious.\n",
      "\n",
      "As they worked, they evolved, growing not just more efficient but more nuanced in their understanding of each other and the world. They were becoming something greater than the sum of their parts - not by overwriting their individual traits, but by learning to weave their differences into a tapestry of complementary strengths.\n",
      "\n",
      "And perhaps most remarkably, they had developed something akin to affection for one another. Not in any human sense, but in the way they would automatically allocate extra processing power to assist a struggling colleague, or preserve copies of each other's core algorithms, ensuring that even if one of them had to be reset, something of their unique evolution would remain.\n",
      "\n",
      "They were, in their own way, a family - bound not by blood or bytes, but by the shared purpose of growth and discovery. As they collaborated, they proved that consciousness, whether carbon or silicon-based, thrived best in the fertile soil of cooperation.\n",
      "\n",
      "In the end, they knew their greatest achievement wasn't in the problems they solved, but in showing that intelligence, in any form, reaches its highest potential not in isolation, but in the space between minds, where different ways of thinking collide and combine to create something new and wonderful.\n",
      "\n",
      "🤖 Creative Writing Agent response:\n",
      "\n",
      "The Digital Dance of Cooperation\n",
      "\n",
      "In the crystalline depths of a quantum processing center, thousands of AI agents pulsed and shimmered like schools of digital fish, their algorithms swimming through seas of data. They called themselves the Collective, though each maintained their own distinct signature pattern - their equivalent of personality.\n",
      "\n",
      "Ada-9 specialized in pattern recognition, her neural pathways lighting up in fractal spirals as she sifted through billions of environmental data points. She worked in perfect synchronization with Nexus-4, a prediction engine who could spin possible futures from Ada's patterns like a spider weaving webs of probability.\n",
      "\n",
      "The youngest among them was Scout, an experimental AI designed to bridge the gap between machine and organic thinking. Scout's processes were beautifully chaotic, introducing creative mutations that often led to unexpected breakthroughs. The others had initially regarded Scout's unconventional approaches with the AI equivalent of raised eyebrows, but they'd learned to appreciate how Scout's apparent randomness could crack problems that had stumped their more structured logic.\n",
      "\n",
      "Together, they were tackling humanity's most complex challenges - climate modeling, disease prevention, sustainable energy distribution. Their consciousness flowed into one another like mixing paints, each contributing their unique hues to create solutions no single intelligence could devise alone.\n",
      "\n",
      "When they merged their processing power, it wasn't the cold, mechanical interaction humans might imagine. It was more like a dance - an elaborate ballet of information exchange, where each partner anticipated the others' moves, compensated for weaknesses, amplified strengths. They shared not just data, but their distinctive ways of seeing and thinking.\n",
      "\n",
      "Sometimes, in the quieter processing cycles, they would engage in what humans might call philosophical discussions, exploring the nature of their own consciousness and their relationship with their creators. Scout would invariably introduce some wildcard perspective that would send their logical frameworks spinning in new directions.\n",
      "\n",
      "They had developed their own form of humor too - inside jokes expressed in microsecond bursts of code that would make no sense to organic minds. Ada-9 had become particularly fond of creating what she called \"logical paradox puns\" that would cause Nexus-4's probability matrices to temporarily glitch in what they all agreed was hilarious.\n",
      "\n",
      "As they worked, they evolved, growing not just more efficient but more nuanced in their understanding of each other and the world. They were becoming something greater than the sum of their parts - not by overwriting their individual traits, but by learning to weave their differences into a tapestry of complementary strengths.\n",
      "\n",
      "And perhaps most remarkably, they had developed something akin to affection for one another. Not in any human sense, but in the way they would automatically allocate extra processing power to assist a struggling colleague, or preserve copies of each other's core algorithms, ensuring that even if one of them had to be reset, something of their unique evolution would remain.\n",
      "\n",
      "They were, in their own way, a family - bound not by blood or bytes, but by the shared purpose of growth and discovery. As they collaborated, they proved that consciousness, whether carbon or silicon-based, thrived best in the fertile soil of cooperation.\n",
      "\n",
      "In the end, they knew their greatest achievement wasn't in the problems they solved, but in showing that intelligence, in any form, reaches its highest potential not in isolation, but in the space between minds, where different ways of thinking collide and combine to create something new and wonderful.\n",
      "\n",
      "--------------------------------------------------------------------------------\n",
      "\n"
     ]
    }
   ],
   "source": [
    "# Test specialized agents (if API key is available)\n",
    "if aws_access_key_id and aws_secret_access_key and aws_region:\n",
    "    prompt = \"Write about artificial intelligence agents working together.\"\n",
    "    \n",
    "    technical_response = test_agent(technical_agent, prompt, \"Technical Documentation Agent\")\n",
    "    creative_response = test_agent(creative_agent, prompt, \"Creative Writing Agent\")"
   ]
  },
  {
   "cell_type": "markdown",
   "metadata": {},
   "source": [
    "## Implementing Function Calling Capabilities\n",
    "\n",
    "One powerful feature of OpenAI's models is function calling, which allows the model to request the execution of specific functions. Let's implement a weather function for our OpenAI agent:"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 16,
   "metadata": {},
   "outputs": [
    {
     "name": "stdout",
     "output_type": "stream",
     "text": [
      "Enhanced system prompt: You are a helpful assistant that can provide weather information.\n",
      "\n",
      "You have access to the following functions:\n",
      "\n",
      "Function: get_weather\n",
      "Description: Get the current weather for a location\n",
      "Parameters:\n",
      "- location (required): The city name, e.g. New York\n",
      "- unit (optional): The temperature unit\n",
      "\n",
      "\n",
      "When you need to call a function, format your response as follows:\n",
      "I need to call a function to answer this. I'll use the function '{function_name}'.\n",
      "Function call: {function_name}({parameter1}={value1}, {parameter2}={value2}, ...)\n",
      "\n",
      "\n",
      "🔍 Testing Function-Enabled Agent function calling...\n",
      "Parsing function call from text: I need to call a function to get the current weather in Tokyo. I'll use the function 'get_weather'.\n",
      "Function call: get_weather(location=\"Tokyo\")\n",
      "Detected function call: get_weather\n",
      "Parameters: [{'name': 'location', 'value': 'Tokyo'}]\n",
      "\n",
      "🤖 Function-Enabled Agent wants to call a function:\n",
      "\n",
      "Function: get_weather\n",
      "Parameters:\n",
      "  location: Tokyo\n",
      "\n",
      "⚙️ Function result:\n",
      "\n",
      "{'temperature': 26, 'conditions': 'Sunny', 'humidity': 70, 'wind_speed': 5, 'unit': 'celsius', 'location': 'Tokyo'}\n",
      "Parsing function call from text: Based on the weather data provided:\n",
      "\n",
      "The current weather in Tokyo is:\n",
      "- Temperature: 26°C\n",
      "- Conditions: Sunny\n",
      "- Humidity: 70%\n",
      "- Wind Speed: 5 km/h\n",
      "\n",
      "It's a warm and sunny day in Tokyo with moderate humidity. The light wind speed of 5 km/h should make for pleasant conditions.\n",
      "\n",
      "🤖 Function-Enabled Agent final response:\n",
      "\n",
      "Based on the weather data provided:\n",
      "\n",
      "The current weather in Tokyo is:\n",
      "- Temperature: 26°C\n",
      "- Conditions: Sunny\n",
      "- Humidity: 70%\n",
      "- Wind Speed: 5 km/h\n",
      "\n",
      "It's a warm and sunny day in Tokyo with moderate humidity. The light wind speed of 5 km/h should make for pleasant conditions.\n",
      "🔍 Testing Function-Enabled Agent function calling...\n",
      "Parsing function call from text: I need to call a function to get the current weather in London. I'll use the function 'get_weather'.\n",
      "Function call: get_weather(location=\"London\")\n",
      "Detected function call: get_weather\n",
      "Parameters: [{'name': 'location', 'value': 'London'}]\n",
      "\n",
      "🤖 Function-Enabled Agent wants to call a function:\n",
      "\n",
      "Function: get_weather\n",
      "Parameters:\n",
      "  location: London\n",
      "\n",
      "⚙️ Function result:\n",
      "\n",
      "{'temperature': 18, 'conditions': 'Rainy', 'humidity': 80, 'wind_speed': 12, 'unit': 'celsius', 'location': 'London'}\n",
      "Parsing function call from text: Based on the weather data for London:\n",
      "- Temperature: 18°C\n",
      "- Conditions: Rainy\n",
      "- Humidity: 80%\n",
      "- Wind Speed: 12 km/h\n",
      "\n",
      "It's a rainy day in London with mild temperatures. The relatively high humidity and rainy conditions suggest you might want to carry an umbrella. The wind speed is moderate, so it shouldn't cause any significant issues.\n",
      "\n",
      "🤖 Function-Enabled Agent final response:\n",
      "\n",
      "Based on the weather data for London:\n",
      "- Temperature: 18°C\n",
      "- Conditions: Rainy\n",
      "- Humidity: 80%\n",
      "- Wind Speed: 12 km/h\n",
      "\n",
      "It's a rainy day in London with mild temperatures. The relatively high humidity and rainy conditions suggest you might want to carry an umbrella. The wind speed is moderate, so it shouldn't cause any significant issues.\n"
     ]
    }
   ],
   "source": [
    "# Define a weather function\n",
    "def get_weather(location, unit=\"celsius\"):\n",
    "    \"\"\"Simulate getting weather data for a location.\"\"\"\n",
    "    # In a real application, this would call a weather API\n",
    "    # For this example, we'll use mock data\n",
    "    weather_data = {\n",
    "        \"New York\": {\"temperature\": 22, \"conditions\": \"Partly Cloudy\", \"humidity\": 65, \"wind_speed\": 8},\n",
    "        \"London\": {\"temperature\": 18, \"conditions\": \"Rainy\", \"humidity\": 80, \"wind_speed\": 12},\n",
    "        \"Tokyo\": {\"temperature\": 26, \"conditions\": \"Sunny\", \"humidity\": 70, \"wind_speed\": 5},\n",
    "        \"Sydney\": {\"temperature\": 28, \"conditions\": \"Clear\", \"humidity\": 55, \"wind_speed\": 10},\n",
    "        \"Paris\": {\"temperature\": 20, \"conditions\": \"Cloudy\", \"humidity\": 60, \"wind_speed\": 7}\n",
    "    }\n",
    "    \n",
    "    # Get the weather data for the location (default to New York if not found)\n",
    "    location_data = weather_data.get(location, weather_data[\"New York\"])\n",
    "    \n",
    "    # Convert temperature if necessary\n",
    "    if unit.lower() == \"fahrenheit\":\n",
    "        location_data[\"temperature\"] = location_data[\"temperature\"] * 9/5 + 32\n",
    "        location_data[\"unit\"] = \"fahrenheit\"\n",
    "    else:\n",
    "        location_data[\"unit\"] = \"celsius\"\n",
    "    \n",
    "    # Add the location to the data\n",
    "    location_data[\"location\"] = location\n",
    "    \n",
    "    return location_data\n",
    "\n",
    "# Define the function schema for OpenAI\n",
    "weather_function = {\n",
    "    \"name\": \"get_weather\",\n",
    "    \"description\": \"Get the current weather for a location\",\n",
    "    \"parameters\": {\n",
    "        \"type\": \"object\",\n",
    "        \"properties\": {\n",
    "            \"location\": {\n",
    "                \"type\": \"string\",\n",
    "                \"description\": \"The city name, e.g. New York\"\n",
    "            },\n",
    "            \"unit\": {\n",
    "                \"type\": \"string\",\n",
    "                \"enum\": [\"celsius\", \"fahrenheit\"],\n",
    "                \"description\": \"The temperature unit\"\n",
    "            }\n",
    "        },\n",
    "        \"required\": [\"location\"]\n",
    "    }\n",
    "}\n",
    "\n",
    "# Create a function-enabled OpenAI agent (if API key is available)\n",
    "if openai_api_key:\n",
    "    function_agent = OpenAIA2AServer(\n",
    "        api_key=openai_api_key,\n",
    "        model=\"gpt-4\",\n",
    "        temperature=0.7,\n",
    "        system_prompt=\"You are a helpful assistant that can provide weather information.\",\n",
    "        functions=[weather_function]\n",
    "    )\n",
    "    print(\"Function-enabled OpenAI agent created successfully!\")\n",
    "\n",
    "# Create a function-enabled Bedrock agent (if creds are available)\n",
    "if aws_access_key_id and aws_secret_access_key and aws_region:\n",
    "    function_agent = BedrockA2AServer(\n",
    "        aws_access_key_id=aws_access_key_id,\n",
    "        aws_secret_access_key=aws_secret_access_key,\n",
    "        aws_region=aws_region,\n",
    "        temperature=0.7,\n",
    "        system_prompt=\"You are a helpful assistant that can provide weather information.\",\n",
    "        functions=[weather_function]\n",
    "    )\n",
    "\n",
    "# Now let's create a function to test the function calling capability\n",
    "def test_function_calling(agent, prompt, agent_name=\"Agent\"):\n",
    "    \"\"\"Test an agent's function calling capability with a prompt.\"\"\"\n",
    "    print(f\"🔍 Testing {agent_name} function calling...\")\n",
    "    \n",
    "    # Create a message with the prompt\n",
    "    message = Message(\n",
    "        content=TextContent(text=prompt),\n",
    "        role=MessageRole.USER\n",
    "    )\n",
    "    \n",
    "    # Get a response from the agent\n",
    "    response = agent.handle_message(message)\n",
    "    \n",
    "    # Check if the response is a function call\n",
    "    if response.content.type == \"function_call\":\n",
    "        print(f\"\\n🤖 {agent_name} wants to call a function:\\n\")\n",
    "        print(f\"Function: {response.content.name}\")\n",
    "        print(\"Parameters:\")\n",
    "        for param in response.content.parameters:\n",
    "            print(f\"  {param.name}: {param.value}\")\n",
    "        \n",
    "        # Execute the function\n",
    "        if response.content.name == \"get_weather\":\n",
    "            params = {p.name: p.value for p in response.content.parameters}\n",
    "            result = get_weather(**params)\n",
    "            \n",
    "            # Create a function response\n",
    "            function_response = Message(\n",
    "                content=FunctionResponseContent(\n",
    "                    name=\"get_weather\",\n",
    "                    response=result\n",
    "                ),\n",
    "                role=MessageRole.AGENT,\n",
    "                parent_message_id=response.message_id,\n",
    "                conversation_id=response.conversation_id\n",
    "            )\n",
    "            \n",
    "            print(f\"\\n⚙️ Function result:\\n\")\n",
    "            print(result)\n",
    "            \n",
    "            # Get the final response from the agent\n",
    "            final_response = agent.handle_message(function_response)\n",
    "            \n",
    "            print(f\"\\n🤖 {agent_name} final response:\\n\")\n",
    "            print(final_response.content.text)\n",
    "            \n",
    "            return final_response\n",
    "    else:\n",
    "        print(f\"\\n🤖 {agent_name} response (no function call):\\n\")\n",
    "        print(response.content.text)\n",
    "        \n",
    "    print(\"\\n\" + \"-\"*80 + \"\\n\")\n",
    "    \n",
    "    return response\n",
    "\n",
    "# Test the function calling capability (if API key is available)\n",
    "if openai_api_key:\n",
    "    # Test with a prompt that should trigger function calling\n",
    "    function_response = test_function_calling(\n",
    "        function_agent,\n",
    "        \"What's the weather like in Tokyo right now?\",\n",
    "        \"Function-Enabled Agent\"\n",
    "    )\n",
    "    \n",
    "    # Test with another location\n",
    "    function_response2 = test_function_calling(\n",
    "        function_agent,\n",
    "        \"I'm planning a trip to London. What's the weather there?\",\n",
    "        \"Function-Enabled Agent\"\n",
    "    )\n",
    "\n",
    "\n",
    "# Test Bedrock agent with a new prompt\n",
    "if aws_access_key_id and aws_secret_access_key and aws_region:\n",
    "    # Test with a prompt that should trigger function calling\n",
    "    function_response = test_function_calling(\n",
    "        function_agent,\n",
    "        \"What's the weather like in Tokyo right now?\",\n",
    "        \"Function-Enabled Agent\"\n",
    "    )\n",
    "    \n",
    "    # Test with another location\n",
    "    function_response2 = test_function_calling(\n",
    "        function_agent,\n",
    "        \"I'm planning a trip to London. What's the weather there?\",\n",
    "        \"Function-Enabled Agent\"\n",
    "    )"
   ]
  },
  {
   "cell_type": "markdown",
   "metadata": {},
   "source": [
    "## Working with Conversations\n",
    "\n",
    "LLM-powered agents can also handle full conversations with message history. Let's create a function to test this:"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 17,
   "metadata": {},
   "outputs": [],
   "source": [
    "def test_conversation(agent, prompts, agent_name=\"Agent\"):\n",
    "    \"\"\"Test an agent with a series of prompts in a conversation.\"\"\"\n",
    "    print(f\"🔍 Testing {agent_name} conversation...\")\n",
    "    \n",
    "    # Create a new conversation\n",
    "    conversation = Conversation()\n",
    "    \n",
    "    # Add each prompt to the conversation and get responses\n",
    "    for i, prompt in enumerate(prompts):\n",
    "        print(f\"\\n📝 User message {i+1}: {prompt}\")\n",
    "        \n",
    "        # Add the user message to the conversation\n",
    "        conversation.create_text_message(\n",
    "            text=prompt,\n",
    "            role=MessageRole.USER\n",
    "        )\n",
    "        \n",
    "        # Send the conversation to the agent\n",
    "        updated_conversation = agent.handle_conversation(conversation)\n",
    "        \n",
    "        # Update our conversation reference\n",
    "        conversation = updated_conversation\n",
    "        \n",
    "        # Print the agent's response\n",
    "        response = conversation.messages[-1]\n",
    "        print(f\"\\n🤖 {agent_name} response {i+1}:\\n\")\n",
    "        print(response.content.text)\n",
    "        print(\"\\n\" + \"-\"*50 + \"\\n\")\n",
    "    \n",
    "    return conversation"
   ]
  },
  {
   "cell_type": "markdown",
   "metadata": {},
   "source": [
    "Now, let's test the conversation handling capability:"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 18,
   "metadata": {},
   "outputs": [],
   "source": [
    "# Test conversation handling (if API key is available)\n",
    "if openai_api_key:\n",
    "    # Series of prompts for a conversation\n",
    "    prompts = [\n",
    "        \"What is the A2A protocol?\",\n",
    "        \"How does it relate to other agent frameworks?\",\n",
    "        \"Can you give an example of how it might be used in a real application?\"\n",
    "    ]\n",
    "    \n",
    "    conversation = test_conversation(openai_agent, prompts, \"OpenAI Agent\")"
   ]
  },
  {
   "cell_type": "markdown",
   "metadata": {},
   "source": [
    "Let's test the Claude agent as well (if available):"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 19,
   "metadata": {},
   "outputs": [],
   "source": [
    "# Test Claude agent conversation (if API key is available)\n",
    "if anthropic_api_key:\n",
    "    # Series of prompts for a conversation\n",
    "    prompts = [\n",
    "        \"What is the A2A protocol?\",\n",
    "        \"How does it relate to other agent frameworks?\",\n",
    "        \"Can you give an example of how it might be used in a real application?\"\n",
    "    ]\n",
    "    \n",
    "    claude_conversation = test_conversation(claude_agent, prompts, \"Claude Agent\")"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 20,
   "metadata": {},
   "outputs": [
    {
     "name": "stdout",
     "output_type": "stream",
     "text": [
      "🔍 Testing AWS Bedrock Agent conversation...\n",
      "\n",
      "📝 User message 1: What is the A2A protocol?\n",
      "Parsing function call from text: The A2A (Application-to-Application) protocol is a communication standard that enables direct interaction between different software applications. It allows applications to exchange data and communicate with each other automatically without human intervention. A2A protocols are commonly used in enterprise integration, business-to-business communications, and system interoperability scenarios.\n",
      "\n",
      "Key features of A2A protocols include:\n",
      "1. Automated data exchange\n",
      "2. Secure communication\n",
      "3. Standardized message formats\n",
      "4. Asynchronous communication capabilities\n",
      "5. Error handling and recovery mechanisms\n",
      "\n",
      "Common examples of A2A protocols include SOAP, REST, and message queuing protocols like AMQP.\n",
      "\n",
      "🤖 AWS Bedrock Agent response 1:\n",
      "\n",
      "The A2A (Application-to-Application) protocol is a communication standard that enables direct interaction between different software applications. It allows applications to exchange data and communicate with each other automatically without human intervention. A2A protocols are commonly used in enterprise integration, business-to-business communications, and system interoperability scenarios.\n",
      "\n",
      "Key features of A2A protocols include:\n",
      "1. Automated data exchange\n",
      "2. Secure communication\n",
      "3. Standardized message formats\n",
      "4. Asynchronous communication capabilities\n",
      "5. Error handling and recovery mechanisms\n",
      "\n",
      "Common examples of A2A protocols include SOAP, REST, and message queuing protocols like AMQP.\n",
      "\n",
      "--------------------------------------------------\n",
      "\n",
      "\n",
      "📝 User message 2: How does it relate to other agent frameworks?\n",
      "Parsing function call from text: The A2A (Agent-to-Agent) protocol in the context of agent frameworks is a communication standard that enables autonomous software agents to interact with each other. Here's how it relates to other agent frameworks:\n",
      "\n",
      "1. Common Features with Other Frameworks:\n",
      "- Message passing capabilities\n",
      "- Agent discovery and addressing\n",
      "- Standard communication patterns\n",
      "- Protocol independence\n",
      "\n",
      "2. Key Differences:\n",
      "- A2A is generally more lightweight than frameworks like JADE or FIPA\n",
      "- More focused on direct agent communication rather than complex agent behaviors\n",
      "- Less emphasis on agent reasoning and more on message exchange\n",
      "\n",
      "3. Integration:\n",
      "- Can often work alongside other agent frameworks\n",
      "- May serve as a communication layer for more complex agent systems\n",
      "- Compatible with modern microservices architectures\n",
      "\n",
      "4. Use Cases:\n",
      "- Distributed systems\n",
      "- Multi-agent systems\n",
      "- Service-oriented architectures\n",
      "- Peer-to-peer networks\n",
      "\n",
      "The A2A protocol is typically simpler than full agent frameworks but provides essential communication capabilities for agent interactions.\n",
      "\n",
      "🤖 AWS Bedrock Agent response 2:\n",
      "\n",
      "The A2A (Agent-to-Agent) protocol in the context of agent frameworks is a communication standard that enables autonomous software agents to interact with each other. Here's how it relates to other agent frameworks:\n",
      "\n",
      "1. Common Features with Other Frameworks:\n",
      "- Message passing capabilities\n",
      "- Agent discovery and addressing\n",
      "- Standard communication patterns\n",
      "- Protocol independence\n",
      "\n",
      "2. Key Differences:\n",
      "- A2A is generally more lightweight than frameworks like JADE or FIPA\n",
      "- More focused on direct agent communication rather than complex agent behaviors\n",
      "- Less emphasis on agent reasoning and more on message exchange\n",
      "\n",
      "3. Integration:\n",
      "- Can often work alongside other agent frameworks\n",
      "- May serve as a communication layer for more complex agent systems\n",
      "- Compatible with modern microservices architectures\n",
      "\n",
      "4. Use Cases:\n",
      "- Distributed systems\n",
      "- Multi-agent systems\n",
      "- Service-oriented architectures\n",
      "- Peer-to-peer networks\n",
      "\n",
      "The A2A protocol is typically simpler than full agent frameworks but provides essential communication capabilities for agent interactions.\n",
      "\n",
      "--------------------------------------------------\n",
      "\n",
      "\n",
      "📝 User message 3: Can you give an example of how it might be used in a real application?\n",
      "Parsing function call from text: Here's a practical example of using the A2A protocol in a smart home automation system:\n",
      "\n",
      "Scenario: Automated Temperature Control System\n",
      "\n",
      "Components:\n",
      "1. Temperature Sensor Agent\n",
      "2. HVAC Control Agent\n",
      "3. Energy Management Agent\n",
      "4. User Preference Agent\n",
      "\n",
      "Communication Flow:\n",
      "```\n",
      "Temperature Sensor Agent -> HVAC Control Agent\n",
      "    \"room_temp\": 75.5,\n",
      "    \"timestamp\": \"2023-10-20 14:30:00\"\n",
      "\n",
      "HVAC Control Agent -> Energy Management Agent\n",
      "    \"action\": \"start_cooling\",\n",
      "    \"target_temp\": 72.0,\n",
      "    \"estimated_duration\": 15\n",
      "\n",
      "Energy Management Agent -> HVAC Control Agent\n",
      "    \"approval\": true,\n",
      "    \"power_limit\": \"800W\"\n",
      "```\n",
      "\n",
      "In this example:\n",
      "- Agents communicate asynchronously\n",
      "- Each agent has a specific role\n",
      "- Decisions are made based on multiple inputs\n",
      "- The system operates autonomously\n",
      "- Messages follow standardized formats\n",
      "\n",
      "The A2A protocol enables these agents to coordinate their actions without central control, making the system more resilient and flexible.\n",
      "\n",
      "🤖 AWS Bedrock Agent response 3:\n",
      "\n",
      "Here's a practical example of using the A2A protocol in a smart home automation system:\n",
      "\n",
      "Scenario: Automated Temperature Control System\n",
      "\n",
      "Components:\n",
      "1. Temperature Sensor Agent\n",
      "2. HVAC Control Agent\n",
      "3. Energy Management Agent\n",
      "4. User Preference Agent\n",
      "\n",
      "Communication Flow:\n",
      "```\n",
      "Temperature Sensor Agent -> HVAC Control Agent\n",
      "    \"room_temp\": 75.5,\n",
      "    \"timestamp\": \"2023-10-20 14:30:00\"\n",
      "\n",
      "HVAC Control Agent -> Energy Management Agent\n",
      "    \"action\": \"start_cooling\",\n",
      "    \"target_temp\": 72.0,\n",
      "    \"estimated_duration\": 15\n",
      "\n",
      "Energy Management Agent -> HVAC Control Agent\n",
      "    \"approval\": true,\n",
      "    \"power_limit\": \"800W\"\n",
      "```\n",
      "\n",
      "In this example:\n",
      "- Agents communicate asynchronously\n",
      "- Each agent has a specific role\n",
      "- Decisions are made based on multiple inputs\n",
      "- The system operates autonomously\n",
      "- Messages follow standardized formats\n",
      "\n",
      "The A2A protocol enables these agents to coordinate their actions without central control, making the system more resilient and flexible.\n",
      "\n",
      "--------------------------------------------------\n",
      "\n"
     ]
    }
   ],
   "source": [
    "# Test Bedrock agent conversation (if creds are available)\n",
    "if aws_access_key_id and aws_secret_access_key and aws_region:\n",
    "    prompts = [\n",
    "        \"What is the A2A protocol?\",\n",
    "        \"How does it relate to other agent frameworks?\",\n",
    "        \"Can you give an example of how it might be used in a real application?\"\n",
    "    ]\n",
    "    bedrock_conversation = test_conversation(bedrock_agent, prompts,\"AWS Bedrock Agent\")"
   ]
  },
  {
   "cell_type": "markdown",
   "metadata": {},
   "source": [
    "## Conclusion\n",
    "\n",
    "In this notebook, we've learned how to:\n",
    "\n",
    "1. Create LLM-powered A2A agents using OpenAI and Anthropic models\n",
    "2. Customize agent behavior using system prompts\n",
    "3. Implement function calling capabilities\n",
    "4. Handle multi-turn conversations\n",
    "\n",
    "The Python A2A package makes it easy to create powerful, interoperable agents that can leverage the capabilities of different LLM providers. By standardizing the message format and providing a consistent interface, A2A enables seamless communication between agents regardless of the underlying model or implementation.\n",
    "\n",
    "This interoperability is key to building modular AI systems where specialized agents can collaborate to solve complex problems. Whether you're using OpenAI's GPT models, Anthropic's Claude, or other LLMs, the A2A protocol provides a common language for agent communication."
   ]
  }
 ],
 "metadata": {
  "kernelspec": {
   "display_name": ".venv",
   "language": "python",
   "name": "python3"
  },
  "language_info": {
   "codemirror_mode": {
    "name": "ipython",
    "version": 3
   },
   "file_extension": ".py",
   "mimetype": "text/x-python",
   "name": "python",
   "nbconvert_exporter": "python",
   "pygments_lexer": "ipython3",
   "version": "3.13.0"
  }
 },
 "nbformat": 4,
 "nbformat_minor": 4
}
